import multiprocessing as mp
import threading as th
import time
from bs4 import BeautifulSoup

"""
分布式爬虫主要是为了非常有效率的抓取网页,
我们的程序一般是单线程跑的, 指令也是一条条处理的,
每执行完一条指令才能跳到下一条. 那么在爬虫的世界里, 这里存在着一个问题.

如果你已经顺利地执行过了前几节的爬虫代码, 你会发现, 
有时候代码运行的时间大部分都花在了下载网页上. 
有时候不到一秒能下载好一张网页的 HTML, 有时候却要几十秒.
 而且非要等到 HTML 下载好了以后, 才能执行网页分析等步骤. 这非常浪费时间.
"""
"""
同时下载, 同时分析的这一种类型的分布式爬虫
"""
"""
1、分布式运算multiprocessing
"""
# def job(q):
#     res=0
#     for i in range(1000):
#         res+=i+i**2+i**3
#     q.put(res)    #queue
#
# if __name__=='__main__':
#     q = mp.Queue()
#     p1 = mp.Process(target=job,args=(q,))
#     p2 = mp.Process(target=job,args=(q,))
#     p1.start()
#     p2.start()
#     p1.join()
#     p2.join()
#     res1 = q.get()
#     res2 = q.get()
#     print(res1+res2)

"""
2、效率对比 threading & multiprocessing
"""
def job(q):
    res = 0
    for i in range(10000000):
        res += i**2 +i**3
    q.put(res) # queue

# 1、创建多进程 multiprocessing
def multicore(): # 代表多线程/多核
    q = mp.Queue()
    p1 = mp.Process(target=job,args=(q,))
    p2 = mp.Process(target=job,args=(q,))
    p3 = mp.Process(target=job,args=(q,))
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    res1 = q.get()
    res2 = q.get()
    res3 = q.get()
    print('multicore:',res1+res2+res3)

# 2、创建多线程 multithread
def multithread():
    q = mp.Queue() # thread可放入process同样的queue中
    t1 = th.Thread(target=job,args=(q,))
    t2 = th.Thread(target=job,args=(q,))
    t3 = th.Thread(target=job,args=(q,))
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    res1 = q.get()
    res2 = q.get()
    res3 = q.get()
    print('multithread:',res1+res2+res3)

# 3、创建普通函数
# 注意，在上面例子中我们建立了三个进程或线程，均对job()进行了三次运算，所以在normal()中我们也让它循环三次
def normal():
    res = 0
    for _ in range(3):
        for i in range(1000000):
            res += i ** 2 + i ** 3
    print('normal:',res)

# 4、计算运行时间
if __name__=='__main__':
    st1 = time.time()
    normal()
    st2 = time.time()
    print('normal time:',st2-st1)
    multicore()
    st3 = time.time()
    print('multicore time:',st3-st2)
    multithread()
    print('multithread time:',time.time()-st3)